package org.chibandroid.android.map;

import java.util.ArrayList;
import java.util.List;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ToggleButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;

public class AndroidMapView extends MapActivity implements LocationListener{

    /** Called when the activity is first created. */

   // ログ出力用のタグ
   private static final String TAG = "AndroidMapView";
   // 地図の初期値
   private static final int INITIAL_ZOOM_LEVE = 18;

   private static final int INITIAL_LATITUDE  = 35853498;
   private static final int INITIAL_LONGITUDE = 139917804;

   private MapView mapView;
   private EditText location;
   private Button btn;
   private ToggleButton TBtn;
   private LocationManager mLocationManager;
   private MapController controller;
   private List<Overlay> overlays;

   private List<String> sLong;
   private List<String> sLat;

	@Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mapView = (MapView) findViewById(R.id.mapview);
        location = (EditText)findViewById(R.id.EditText01);
        btn = (Button)findViewById(R.id.Button01);
        TBtn = (ToggleButton)findViewById(R.id.TButton01);
        TBtn.setTextOff("");
        TBtn.setTextOn("");

        sLong = new ArrayList<String>();
        sLat = new ArrayList<String>();

        btn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	writeGPSAddress();
            }
        });

        TBtn.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if(isChecked){
			        mapView.setBuiltInZoomControls(true);
			        mapView.displayZoomControls(true);
				}else{
			        mapView.setBuiltInZoomControls(false);
			        mapView.displayZoomControls(false);
				}
			}
        }
        );

        // 位置とズームレベルの初期状態を設定する
        controller = mapView.getController();
        GeoPoint point = new GeoPoint(INITIAL_LATITUDE, INITIAL_LONGITUDE);
        controller.setCenter(point);
        controller.setZoom(INITIAL_ZOOM_LEVE);

        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

        overlays = mapView.getOverlays();
        // イメージを地図上に表示する
        setOverlay(point);

    }

	private boolean writeGPSAddress(){
        try {
			File path = Environment.getExternalStorageDirectory();
			String _path = path.getAbsolutePath() + "/RoteLocation.kml";
            FileOutputStream fileOutputStream = new FileOutputStream(_path);
            fileOutputStream.write(makeGPSPoint().getBytes());
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
        	return false;
        } catch (IOException e) {
        	return false;
        }
		return true;
	}

	private String makeGPSPoint(){

		String _point;

		_point = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+'\n';
		_point += "<kml xmlns=\"http://earth.google.com/kml/2.2\">"+'\n';
		_point += "<Document>"+'\n';
		_point += "<name>GE2ADT</name>"+'\n';

		for(int i=0;i<sLong.size();i++){
			_point += "<Placemark><name>"+String.valueOf(i);
			_point += "</name><description>GE2ADT Route</description><Point><coordinates>";
			_point += sLong.get(i)+","+sLat.get(i);
			_point += ",0</coordinates></Point></Placemark>"+'\n';
		}
		_point += "</Document>"+'\n';
		_point += "</kml>"+'\n';

		return _point;
	}

    @Override
    protected void onPause() {

    	if (mLocationManager != null) {
            mLocationManager.removeUpdates(this);
        }

        super.onPause();
    }

    @Override
    protected void onResume() {
        if (mLocationManager != null) {
            mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER,
                0,
                0,
                this);
        }

        super.onResume();
    }

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	private IconOverlay overlay;
	private Bitmap icon = null;

	private void setOverlay(GeoPoint point) {

	       // Overlayクラスを生成する
		   if(icon!=null){
			   icon.recycle();
		   }

			Matrix matrix = new Matrix();
			matrix.postScale(0.5f, 0.5f);

	       Bitmap wicon = BitmapFactory.decodeResource(getResources(),R.drawable.point);
	       icon = Bitmap.createBitmap(wicon, 0, 0, wicon.getWidth(), wicon.getHeight(),matrix,true);
	       overlay = new IconOverlay(icon, point);
	       overlays.add(overlay);

	}

	   // 地図上に表示されるオーバーレイ
	private class IconOverlay extends Overlay{

	       // 描画するアイコン
		private Bitmap mIcon;
		private int mOffsetX;
		private int mOffsetY;
		private String sLocation;

       // アイコンを表示する位置
		private GeoPoint mPoint;

		public IconOverlay(Bitmap icon, GeoPoint initial) {
           // アイコンと、アイコンの中心のオフセット
			mIcon = icon;
			mOffsetX = 0 - icon.getWidth() / 2;
			mOffsetY = 0 - icon.getHeight();
			mPoint = initial;
			sLocation = "";
		}

       // 地図のタップ時に呼び出される
       @Override
       public boolean onTap(GeoPoint point, MapView mapView) {

           mPoint = point;
           MoveTo(mPoint);
           controller.animateTo(mPoint);
           return true;
       }



       public void MoveTo(GeoPoint point){

           mPoint = point;

           BigDecimal _Long = new BigDecimal(point.getLongitudeE6()).divide(new BigDecimal(1000000));
           BigDecimal _Lat = new BigDecimal(point.getLatitudeE6()).divide(new BigDecimal(1000000));

           sLocation = "緯度:" + String.valueOf(_Long) +'\n';
           sLocation += "経度:" + String.valueOf(_Lat);

           location.setText(sLocation);
           sLong.add(String.valueOf(_Long));
           sLat.add(String.valueOf(_Lat));

       }

       // 地図の描画時に、shadow=true, shadow=falseと2回呼び出される
       @Override
       public void draw(Canvas canvas, MapView mapView,boolean shadow) {

           super.draw(canvas, mapView, shadow);

           // 地図上の場所と、描画用のCanvasの座標の変換
           Projection projection = mapView.getProjection();
           Point point = new Point();
           projection.toPixels(mPoint, point);
           point.offset(mOffsetX, mOffsetY);

           // アイコンを描画
           if (!shadow) {
               canvas.drawBitmap(mIcon, point.x, point.y, new Paint());
           }else{
        	   Paint paint = new Paint();
        	   paint.setAntiAlias(true);
        	   paint.setColor(Color.GRAY);
        	   paint.setStrokeCap(Cap.ROUND);
        	   paint.setStrokeWidth(5);
        	   canvas.drawCircle(point.x+(mIcon.getWidth()/2), point.y+mIcon.getHeight(), 10, paint);
           }
       }

   }


	@Override
    public void onLocationChanged(Location location) {

		GeoPoint gp =
			new GeoPoint((int)(location.getLatitude() * 1E6),(int)(location.getLongitude() * 1E6));
		controller.animateTo(gp);
		overlay.MoveTo(gp);

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

 	   switch (status) {
        	case LocationProvider.AVAILABLE:
        		Log.v("Status", "AVAILABLE");
        		break;
        	case LocationProvider.OUT_OF_SERVICE:
        		Log.v("Status", "OUT_OF_SERVICE");
        		break;
        	case LocationProvider.TEMPORARILY_UNAVAILABLE:
            Log.v("Status", "TEMPORARILY_UNAVAILABLE");
            break;
        	}

    }

};